package server

import (
	"net/http"
	"cloud_worm/router/config"
	"time"
	"github.com/golang/glog"
	"cloud_worm/router/server/router"
	"cloud_worm/util/uratelimit"
	"cloud_worm/router/server/filesrv"
	"cloud_worm/util/umodels"
	"sync"
)

func FileSrv(wg *sync.WaitGroup)  {
	http.Handle("/", http.FileServer(http.Dir(config.ConfInst.Server.FileBaseDir)))
	fileSrv := &http.Server{
		Addr: config.ConfInst.LocalAddr + ":" + config.ConfInst.Server.FilePort,
		Handler: nil,
		IdleTimeout: 90 * time.Second,
	}

	go func(wg *sync.WaitGroup) {
		wg.Add(1)

		glog.Infof("start file server '%s:%s' loop.", config.ConfInst.LocalAddr, config.ConfInst.Server.FilePort)

		var err error
		if config.ConfInst.TLSCertInfo.PemFile != "" {
			err = fileSrv.ListenAndServeTLS(config.ConfInst.TLSCertInfo.PemFile, config.ConfInst.TLSCertInfo.KeyFile)
			if err != nil {
				glog.Fatalf("file server start error: %s", err.Error())
			}
		} else {
			err = fileSrv.ListenAndServe()
			if err != nil {
				glog.Fatalf("file server start error: %s", err.Error())
			}
		}
		wg.Done()
	}(wg)

	return
}

func RouterSrv(wg *sync.WaitGroup)  {
	// 启动协程，刷新router config信息
	dbConfig := umodels.DbInfo{
		//RunMode: config.ConfInst.RunMode,
		RunMode: "pub",
		UserName: config.ConfInst.Mysql.UserName,
		Password: config.ConfInst.Mysql.Password,
		Domain: config.ConfInst.Mysql.Host,
		Port: config.ConfInst.Mysql.Port,
		Database: config.ConfInst.Mysql.Database,
	}
	umodels.OrmInit(dbConfig)
	router.RouteSrvMap.LoadConfigLoop(wg)

	// http api server
	mux := http.NewServeMux()

	// 注册服务
	registerApi(mux)

	httpSrv := &http.Server{
		Addr: config.ConfInst.LocalAddr + ":" + config.ConfInst.Server.WebPort,
		Handler: mux,
		IdleTimeout: 90 * time.Second,
	}

	go func(wg *sync.WaitGroup) {
		wg.Add(1)

		glog.Infof("start router server '%s:%s' loop.", config.ConfInst.LocalAddr, config.ConfInst.Server.WebPort)
		var err error
		if config.ConfInst.TLSCertInfo.PemFile != "" {
			err = httpSrv.ListenAndServeTLS(config.ConfInst.TLSCertInfo.PemFile, config.ConfInst.TLSCertInfo.KeyFile)
			if err != nil {
				glog.Fatalf("http start error: " + err.Error())
			}
		} else {
			err = httpSrv.ListenAndServe()
			if err != nil {
				glog.Fatalf("http start error: " + err.Error())
			}
		}
		wg.Done()
	}(wg)

	return
}

func registerApi(mux *http.ServeMux) error {

	// config
	mux.HandleFunc(router.UriConfigApi, func(rw http.ResponseWriter, req *http.Request) {
		router.ConfigApi(rw, req)
	})
	uratelimit.RegisterTokenBucket(router.UriConfigApi, router.RateBucket, router.MaxBucketCnt)
	mux.HandleFunc("/api/all", func(rw http.ResponseWriter, req *http.Request) {
		router.ConfigAll(rw, req)
	})

	// file
	mux.HandleFunc("/worm/client/max_ver", func(rw http.ResponseWriter, req *http.Request) {
		filesrv.MaxAgentVersion(rw, req)
	})
	mux.HandleFunc("/gray/router/get", func(rw http.ResponseWriter, req *http.Request) {
		filesrv.GrayRouterGet(rw, req)
	})
	mux.HandleFunc("/gray/router/set", func(rw http.ResponseWriter, req *http.Request) {
		filesrv.GrayRouterSet(rw, req)
	})

	// file upload
	mux.HandleFunc("/upload/worm", func(rw http.ResponseWriter, req *http.Request) {
		filesrv.UploadWormFile(rw, req)
	})
	// weapon类文件的上传
	mux.HandleFunc("/upload/weapon", func(rw http.ResponseWriter, req *http.Request) {
		filesrv.UploadWeaponFile(rw, req)
	})

	return nil
}
